"""Deployment资源Markdown写入器模块"""

from typing import Dict, Any, List, Optional
import yaml
from src.writers.base import Writer
from src.utils.markdown_builder import MarkdownBuilder
import logging

class DeploymentWriter(Writer):
    """
    Deployment资源Markdown写入器
    负责将提取的Deployment资源信息写入Markdown文件
    """
    
    def __init__(self, config_manager=None, logger: Optional[logging.Logger] = None):
        """
        初始化Deployment写入器
        
        Args:
            config_manager: 配置管理器
            logger: 日志记录器，可选
        """
        super().__init__(config_manager, logger)
    
    def write(self, data: Dict[str, Any], output_path: str) -> None:
        """
        将提取的Deployment信息写入Markdown
        
        Args:
            data: 提取的Deployment信息
            output_path: 输出文件路径
        """
        if not data or data.get("kind") != "Deployment":
            self.logger.warning(f"无效的Deployment数据: {data.get('name', '未知')}")
            return
        
        # 创建Markdown构建器
        md = self.create_markdown_builder()
        md.enable_section_numbers()  # 确保启用章节编号
        
        # 收集节标题，用于生成目录
        sections = ["基本信息", "标签选择器", "副本设置", "部署策略", "容器", "存储卷"]
        
        # 标题
        md.disable_section_numbers()  # 顶级标题不使用编号
        md.header(f"Deployment: {data.get('name', '未知')}", 1)
        md.enable_section_numbers()  # 重新启用章节编号
        
        # 命名空间
        md.bold("命名空间:").text(f" {data.get('namespace', 'default')}").newline(2)
        
        # 目录
        if len(sections) > 3:  # 只有当节较多时才添加目录
            md.disable_section_numbers()  # 目录标题不使用编号
            
            # 创建带编号的目录项和锚点
            md._content.write("## 目录\n\n")
            for i, section in enumerate(sections, 1):
                section_anchor = f"{i}-{section}".lower().replace(" ", "-")
                md._content.write(f"- [{i}. {section}](#{section_anchor})\n")
            md._content.write("\n")
            
            md.enable_section_numbers()  # 重新启用章节编号
        
        # 基本信息
        md.header("基本信息", 2)
        
        # 基本元数据表
        basic_info = {
            "名称": data.get("name", ""),
            "命名空间": data.get("namespace", "default"),
            "创建时间": data.get("creation_timestamp", ""),
            "副本数": data.get("replicas", 1)
        }
        md.dict_table(basic_info)
        
        # 标签和注解
        if data.get("labels"):
            md.header("标签", 3)
            md.dict_table(data.get("labels", {}))
        
        if data.get("annotations"):
            md.header("注解", 3)
            md.dict_table(data.get("annotations", {}))
        
        # 选择器
        md.header("标签选择器", 2)
        if data.get("selector"):
            md.dict_table(data.get("selector", {}))
        else:
            md.paragraph("无选择器配置")
        
        # 副本设置
        md.header("副本设置", 2)
        md.bold("当前副本数:").text(f" {data.get('replicas', 1)}").newline(2)
        
        # 部署策略
        md.header("部署策略", 2)
        if data.get("strategy"):
            strategy = data.get("strategy", {})
            strategy_type = strategy.get("type", "RollingUpdate")
            md.bold("策略类型:").text(f" {strategy_type}").newline(2)
            
            if strategy_type == "RollingUpdate" and "rollingUpdate" in strategy:
                rolling_update = strategy.get("rollingUpdate", {})
                max_surge = rolling_update.get("maxSurge", "25%")
                max_unavailable = rolling_update.get("maxUnavailable", "25%")
                
                md.bold("最大超量:").text(f" {max_surge}").newline(2)
                md.bold("最大不可用:").text(f" {max_unavailable}").newline(2)
        else:
            md.paragraph("使用默认部署策略")
        
        # 容器信息
        md.header("容器", 2)
        if data.get("containers"):
            for i, container in enumerate(data.get("containers", [])):
                self._write_container_info(md, container, i + 1)
        else:
            md.paragraph("无容器配置")
        
        # 卷信息
        md.header("存储卷", 2)
        if data.get("volumes"):
            for i, volume in enumerate(data.get("volumes", [])):
                self._write_volume_info(md, volume, i + 1)
        else:
            md.paragraph("无存储卷配置")
        
        # 服务账号
        if data.get("service_account"):
            md.header("服务账号", 2)
            md.bold("服务账号名称:").text(f" {data.get('service_account', 'default')}").newline(2)
        
        # 生成Markdown文件
        self.write_markdown(str(md), output_path)
    
    def _write_container_info(self, md: MarkdownBuilder, container: Dict[str, Any], index: int) -> None:
        """
        写入容器信息
        
        Args:
            md: Markdown构建器
            container: 容器信息字典
            index: 容器索引
        """
        container_name = container.get("name", f"container-{index}")
        md.header(f"容器 {index}: {container_name}", 3)
        
        # 基本信息
        with md.list() as lst:
            lst.item(f"**镜像:** {container.get('image', '未指定')}")
            
            image_pull_policy = container.get("imagePullPolicy", "")
            if image_pull_policy:
                lst.item(f"**镜像拉取策略:** {image_pull_policy}")
        
        # 端口
        if container.get("ports"):
            md.header("端口", 4)
            
            headers = ["名称", "容器端口", "协议"]
            rows = []
            
            for port in container.get("ports", []):
                rows.append([
                    port.get("name", ""),
                    str(port.get("containerPort", "")),
                    port.get("protocol", "TCP")
                ])
            
            md.table(headers, rows)
        
        # 环境变量
        if container.get("env"):
            md.header("环境变量", 4)
            
            headers = ["名称", "值", "来源"]
            rows = []
            
            for env in container.get("env", []):
                name = env.get("name", "")
                value = env.get("value", "")
                value_from = ""
                
                if "value_from" in env:
                    value_from_dict = env.get("value_from", {})
                    if "configMapKeyRef" in value_from_dict:
                        cm_ref = value_from_dict.get("configMapKeyRef", {})
                        value_from = f"ConfigMap: {cm_ref.get('name', '')}.{cm_ref.get('key', '')}"
                    elif "secretKeyRef" in value_from_dict:
                        secret_ref = value_from_dict.get("secretKeyRef", {})
                        value_from = f"Secret: {secret_ref.get('name', '')}.{secret_ref.get('key', '')}"
                    elif "fieldRef" in value_from_dict:
                        field_ref = value_from_dict.get("fieldRef", {})
                        value_from = f"Field: {field_ref.get('fieldPath', '')}"
                
                rows.append([name, value, value_from])
            
            md.table(headers, rows)
        
        # 资源请求和限制
        if container.get("resources"):
            md.header("资源配置", 4)
            
            resources = container.get("resources", {})
            requests = resources.get("requests", {})
            limits = resources.get("limits", {})
            
            if requests:
                md.bold("请求:").newline()
                
                with md.list() as lst:
                    for resource_type, value in requests.items():
                        lst.item(f"{resource_type}: {value}")
                
            if limits:
                md.bold("限制:").newline()
                
                with md.list() as lst:
                    for resource_type, value in limits.items():
                        lst.item(f"{resource_type}: {value}")
        
        # 存活探针
        if container.get("liveness_probe"):
            md.header("存活探针", 4)
            self._write_probe(md, container.get("liveness_probe", {}))
        
        # 就绪探针
        if container.get("readiness_probe"):
            md.header("就绪探针", 4)
            self._write_probe(md, container.get("readiness_probe", {}))
        
        # 卷挂载
        if container.get("volume_mounts"):
            md.header("卷挂载", 4)
            
            headers = ["名称", "挂载路径", "只读"]
            rows = []
            
            for mount in container.get("volume_mounts", []):
                name = mount.get("name", "")
                path = mount.get("mount_path", "")
                read_only = "是" if mount.get("read_only", False) else "否"
                
                rows.append([name, path, read_only])
            
            md.table(headers, rows)
    
    def _write_probe(self, md: MarkdownBuilder, probe: Dict[str, Any]) -> None:
        """
        写入探针信息
        
        Args:
            md: Markdown构建器
            probe: 探针信息字典
        """
        with md.list() as lst:
            # 初始延迟
            if "initial_delay_seconds" in probe:
                lst.item(f"初始延迟: {probe.get('initial_delay_seconds')}秒")
            
            # 超时
            if "timeout_seconds" in probe:
                lst.item(f"超时: {probe.get('timeout_seconds')}秒")
            
            # 周期
            if "period_seconds" in probe:
                lst.item(f"周期: {probe.get('period_seconds')}秒")
            
            # 成功阈值
            if "success_threshold" in probe:
                lst.item(f"成功阈值: {probe.get('success_threshold')}")
            
            # 失败阈值
            if "failure_threshold" in probe:
                lst.item(f"失败阈值: {probe.get('failure_threshold')}")
            
            # 探针类型和参数
            if "http_get" in probe:
                http_get = probe.get("http_get", {})
                path = http_get.get("path", "/")
                port = http_get.get("port", 80)
                lst.item(f"HTTP GET 探针: {path} (端口: {port})")
            elif "tcp_socket" in probe:
                tcp_socket = probe.get("tcp_socket", {})
                port = tcp_socket.get("port", 80)
                lst.item(f"TCP Socket 探针: 端口 {port}")
            elif "exec" in probe:
                exec_probe = probe.get("exec", {})
                command = exec_probe.get("command", [])
                if command:
                    cmd_str = " ".join(command)
                    lst.item(f"Exec 探针: `{cmd_str}`")
    
    def _write_volume_info(self, md: MarkdownBuilder, volume: Dict[str, Any], index: int) -> None:
        """
        写入卷信息
        
        Args:
            md: Markdown构建器
            volume: 卷信息字典
            index: 卷索引
        """
        volume_name = volume.get("name", f"volume-{index}")
        md.header(f"卷 {index}: {volume_name}", 3)
        md.newline()
        
        # 确定卷类型并格式化
        if "config_map" in volume:
            config_map = volume.get("config_map", {})
            md.bold("类型:").text(" ConfigMap").newline(2)
            md.bold("ConfigMap名称:").text(f" {config_map.get('name', '')}").newline(2)
            
            if "items" in config_map:
                md.bold("配置项:").newline()
                
                with md.list() as lst:
                    for item in config_map.get("items", []):
                        key = item.get("key", "")
                        path = item.get("path", "")
                        lst.item(f"{key} -> {path}")
                md.newline()
        
        elif "secret" in volume:
            secret = volume.get("secret", {})
            md.bold("类型:").text(" Secret").newline(2)
            md.bold("Secret名称:").text(f" {secret.get('name', '')}").newline(2)
            
            if "items" in secret:
                md.bold("配置项:").newline()
                
                with md.list() as lst:
                    for item in secret.get("items", []):
                        key = item.get("key", "")
                        path = item.get("path", "")
                        lst.item(f"{key} -> {path}")
                md.newline()
        
        elif "persistent_volume_claim" in volume:
            pvc = volume.get("persistent_volume_claim", {})
            md.bold("类型:").text(" PersistentVolumeClaim").newline(2)
            md.bold("PVC名称:").text(f" {pvc.get('claim_name', '')}").newline(2)
            md.bold("只读:").text(f" {'是' if pvc.get('read_only', False) else '否'}").newline(2)
        
        elif "empty_dir" in volume:
            empty_dir = volume.get("empty_dir", {})
            md.bold("类型:").text(" emptyDir").newline(2)
            
            if "medium" in empty_dir:
                md.bold("存储介质:").text(f" {empty_dir.get('medium', 'Memory')}").newline(2)
            
            if "size_limit" in empty_dir:
                md.bold("大小限制:").text(f" {empty_dir.get('size_limit', '')}").newline(2)
        
        elif "host_path" in volume:
            host_path = volume.get("host_path", {})
            md.bold("类型:").text(" hostPath").newline(2)
            md.bold("路径:").text(f" {host_path.get('path', '')}").newline(2)
            
            if "type" in host_path:
                md.bold("类型:").text(f" {host_path.get('type', '')}").newline(2)
        
        else:
            # 处理其他可能的卷类型
            volume_type = next((k for k in volume.keys() if k != "name"), "unknown")
            if volume_type != "unknown":
                md.bold("类型:").text(f" {volume_type}").newline(2)
                md.bold("详细信息:").newline()
                
                with md.code_block("yaml"):
                    md.text(yaml.dump(volume, default_flow_style=False))
                md.newline()
        
        # 在每个卷信息块之后添加额外的空行
        md.newline()